package org.tokaf.datasearcher;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Vector;

import org.tokaf.MyVectorCompare;
import org.tokaf.TopKElement;
import org.tokaf.normalizer.SimpleNormalizer;

/**
 * <p>MemSearcher forms virtual triples. It gets arraylist of TopKElements.
 * Subject of these triples are the names of elements, predicate is
 * propertySearched and objects are the rating of elements. </p> <p>This
 * DataSearcher can be created from output of some other top-k algorithm.</p>
 * <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public class MemSearcher extends DataSearcher {
	ArrayList topK;

	int index = -1;

	String propertySearched;

	public MemSearcher(String property, ArrayList al) {
		topK = al;
		propertySearched = property;
		name = property;
		if (topK.size() > 0)
			index = 0;
	}

	public boolean needsSort() {
		return false;
	}

	public void sort(int index) {
		throw new UnsupportedOperationException();
	}
	

	public SimpleNormalizer getDefaultNormalizer() {
		return new SimpleNormalizer();
	}

	public Object clone() {
		MemSearcher newInstance = new MemSearcher(this.propertySearched,
				this.topK);
		newInstance.initSource(this);
		newInstance.initSearchTime = this.initSearchTime;
		newInstance.initSourceTime = this.initSourceTime;
		newInstance.norm = this.norm;
		newInstance.name = this.name;

		newInstance.index = this.index;
		newInstance.propertySearched = this.propertySearched;
		newInstance.topK = this.topK;
		return newInstance;
	}

	public int initSource(DataSearcher searcher) {
		if (searcher instanceof MemSearcher) {
			topK = ((MemSearcher) searcher).topK;
			return 1;
		}
		return -1;
	}

	public Object getField(int i) {
		return getField(i, index);

	}

	public Object getField(int i, int row) {
		if (i == 2)
			return new Double(((TopKElement) topK.get(row)).rating);
		else if (i == 0)
			return ((TopKElement) topK.get(row)).name;
		else if (i == 1)
			return propertySearched;
		return null;
	}

	public Object getFieldAtPosition(int index, int position) {
		return getField(index, position);
	}

	public int advance() {
		if (topK == null || index < 0 || topK.size() <= index + 1) {
			index++;
			return -1;
		}
		index++;
		return index;
	}

	public void initSearch(String query) {
		long startTime = System.nanoTime();
		MyVectorCompare comp = new MyVectorCompare(2, norm);
		Collections.sort(topK, comp);
		initSearchTime += System.nanoTime() - startTime;
	}

	public int initSource(String db) {
		initSourceTime = 0;
		return 0;
	}

	public Object findObject(Object obj, int position, int index) {
		if (index == 1)
			return propertySearched;
		if (position == 0) {
			for (int i = 0; i < topK.size(); i++) {
				if (((TopKElement) topK.get(i)).name.equals(obj.toString())) {
					if (index == 2)
						return new Double(((TopKElement) topK.get(i)).rating);
				}

			}
		}
		return null;
	}

	public int getPosistion() {
		return index;
	}

	public boolean hasNext() {
		if (index < 0 || index >= topK.size())
			return false;
		return true;
	}

	public Object next() {
		Vector v = new Vector();
		v.add(((TopKElement) topK.get(index)).name);
		v.add(propertySearched);
		v.add(new Double(((TopKElement) topK.get(index)).rating));
		index++;
		return v;
	}

	public void resetSearch() {
		if (index != -1)
			index = 0;
	}

}
